/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import React, { useCallback, useState, useEffect } from 'react';
import { message, Spin } from 'antd';
import { useDebounceFn } from 'ahooks';
import { isFunction } from 'lodash';
import { crypto } from '@/utils/encryption';

/**
 * 异步请求下载路径后再去下载
 * 当有requestFunc时，则是请求接口后拿到地址再去下载
 * 否则就是通过form直接下载
 * @param {Promise} requestFunc 用于请求下载路径的一个promise函数
 * @param {object | Function} data 下载所需的参数
 * @param {string} action 下载地址
 * @param {string} method 下载方式
 */
export default function AsyncDownLoad({
  requestFunc,
  action,
  data = {},
  method = 'GET',
  children,
  disabled,
  onClick,
  ...rest
}) {
  const [loading, setLoading] = useState(false);

  const downLoad = useCallback(async (path = '', query = {}, reqMethod) => {
    if (path === '') {
      message.error('暂无下载地址！');
      return;
    }
    const form = document.createElement('form');
    form.method = reqMethod;
    form.action = await crypto({ url: path });
    form.style = 'display: none;';
    form.target = 'form_iframe';
    if (!document.getElementById('form_iframe')) {
      const form_iframe = document.createElement('iframe');
      form_iframe.id = 'form_iframe';
      form_iframe.name = 'form_iframe';
      form_iframe.style = 'display: none;';
      document.body.appendChild(form_iframe);
    }
    document.body.appendChild(form);
    Object.keys(query).forEach(item => {
      const input = document.createElement('input');
      input.type = 'hidden';
      input.name = item;
      input.value = query[item] || '';
      if (query[item]) {
        form.appendChild(input);
      }
    });

    form.submit();
    form.remove();
    setLoading(false);
  }, []);

  const { run } = useDebounceFn(
    (action_p, data_p, method_p) => {
      setLoading(true);
      if (action_p) {
        let params = {};
        if (isFunction(data_p)) {
          params = data_p();
        }
        downLoad(action_p, params, method_p);
      } else {
        requestFunc().then(res => {
          const {
            data: { path },
          } = res;
          const url = path || res.data;
          setLoading(false);
          if (!url) {
            message.error('暂无下载地址！');
          } else {
            downLoad(url, data_p, method_p);
          }
        });
      }
    },
    {
      wait: 1000,
      leading: true,
      trailing: false,
    },
  );

  const onDownloadClick = useCallback(
    () => {
      // 兼容自定义点击事件，如果没传，则直接调用下载方法
      if (onClick && !disabled) {
        onClick(() => run(action, data, method));
        return;
      }
      if (!disabled) {
        run(action, data, method);
      }
    },
    [action, data, method, run, disabled],
  );

  useEffect(() => {
    setLoading(false);
  }, []);

  return (
    <span onClick={e => !loading && onDownloadClick(e)} className={rest.className}>
      <Spin size="small" spinning={loading}>
        {React.cloneElement(children, { disabled })}
      </Spin>
    </span>
  );
}

AsyncDownLoad.defaultProps = {
  requestFunc: async () => ({ data: { path: null } }), // 用于异步请求下载路径
  data: {}, // 下载所需的参数，可以是个函数
};
